package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.PageDto;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.enums.HttpEnum;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import com.itheima.reggie.utils.BeanUtil;
import com.itheima.reggie.utils.LoginThreadLocal;
import com.itheima.reggie.utils.PageUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 套餐(Setmeal)表服务实现类
 *
 * @author shenjiaqi
 * @since 2024-02-06 00:30:52
 */
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
    @Resource
    private SetmealDishService setmealDishService;
    @Resource
    private CategoryService categoryService;

    /**
     * 套餐新增
     *
     * @param dto
     * @return
     */
    @Transactional
    @Override
    public R add(SetmealDto dto) {
        if (null == dto) {
            return R.error(HttpEnum.PARAMETER_NULL.getMsg());
        }
        // stemeal主体解析封装
        Setmeal setmeal = BeanUtil.cloneBean(dto, Setmeal.class);
        if (null == setmeal) {
            return R.error(HttpEnum.PARAMETER_NULL.getMsg());
        }
        setmeal.setCreateUser(LoginThreadLocal.getCurrent());
        setmeal.setUpdateUser(LoginThreadLocal.getCurrent());
        setmeal.setCreateTime(new Date());
        setmeal.setUpdateTime(new Date());
        // 保存
        save(setmeal);
        // stemealDish解析封装
        List<SetmealDish> setmealDishes = dto.getSetmealDishes();
        if (!CollectionUtils.isEmpty(setmealDishes)) {
            setmealDishes.stream()
                    .filter(setmealDish -> Objects.nonNull(setmealDish) && StringUtils.isNotBlank(setmealDish.getDishId()))
                    .forEach(setmealDish -> {
                        setmealDish.setSetmealId(setmeal.getId().toString());
                        setmealDish.setCreateUser(LoginThreadLocal.getCurrent());
                        setmealDish.setUpdateUser(LoginThreadLocal.getCurrent());
                        setmealDish.setCreateTime(new Date());
                        setmealDish.setUpdateTime(new Date());
                    });
            // 批量插入
            setmealDishService.saveBatch(setmealDishes);
        }
        return R.success("套餐新增成功");
    }

    /**
     * 套餐分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public R pageList(PageDto dto) {
        if (null == dto) {
            return R.error(HttpEnum.PARAMETER_NULL);
        }
        PageUtils.setPage(dto);

        Page<Setmeal> setmealPage = page(new Page<>(dto.getPage(), dto.getPageSize()), Wrappers.<Setmeal>lambdaQuery()
                .eq(Setmeal::getIsDeleted, 0)
                .like(StringUtils.isNotBlank(dto.getName()), Setmeal::getName, dto.getName())
                .orderByDesc(Setmeal::getUpdateTime));
        if (CollectionUtils.isEmpty(setmealPage.getRecords())) {
            return R.success(new Page<SetmealDto>());
        }
        // 分类Id集合
        List<Long> categoryIds = setmealPage.getRecords().stream()
                .map(Setmeal::getCategoryId).collect(Collectors.toList());
        List<Category> categoryList = categoryService.list(Wrappers.<Category>lambdaQuery()
                .in(Category::getId, categoryIds));

        // id:name
        Map<Long, String> catrgoryMap = categoryList.stream().collect(Collectors.toMap(Category::getId, Category::getName));

        List<SetmealDto> setmealDtoList = setmealPage.getRecords().stream()
                .map(setmeal -> {
                    SetmealDto setmealDto = BeanUtil.cloneBean(setmeal, SetmealDto.class);
                    setmealDto.setCategoryName(
                            catrgoryMap.getOrDefault(setmeal.getCategoryId(), ""));
                    return setmealDto;
                }).collect(Collectors.toList());

        Page<SetmealDto> setmealDtoPage = new Page<>(dto.getPage(), dto.getPageSize());
        BeanUtils.copyProperties(setmealPage, setmealDtoPage, "records");
        setmealDtoPage.setRecords(setmealDtoList);
        return R.success(setmealDtoPage);
    }

    /**
     * 单个套餐回显
     *
     * @param id
     * @return
     */
    @Override
    public R getWithId(Long id) {
        if (null == id) {
            return R.error(HttpEnum.PARAMETER_NULL);
        }
        Setmeal byId = getById(id);
        if (null == byId) {
            return R.error(HttpEnum.DATA_NULL);
        }
        SetmealDto setmealDto = BeanUtil.cloneBean(byId, SetmealDto.class);
        if (null == byId.getCategoryId()) {
            return R.error("该套餐绑定分类Id为null");
        }
        Category category = categoryService.getById(byId.getCategoryId());
        if (null == category) {
            return R.error(HttpEnum.DATA_NULL);
        }
        //   setmealDto.setCategoryName(StringUtils.isBlank(category.getName()) ? "" : category.getName());
        setmealDto.setCategoryName(StringUtils.defaultIfBlank(category.getName(), ""));

        // 绑定菜品信息
        List<SetmealDish> setmealDishList = setmealDishService.list(Wrappers.<SetmealDish>lambdaQuery()
                .eq(null != byId.getId(), SetmealDish::getSetmealId, byId.getId())
                .eq(SetmealDish::getIsDeleted, 0));
        setmealDto.setSetmealDishes(setmealDishList);
        return R.success(setmealDto);
    }

    /**
     * 套餐修改
     *
     * @param dto
     * @return
     */
    @Transactional
    @Override
    public R updateWithEntity(SetmealDto dto) {
        if (null == dto) {
            return R.error(HttpEnum.PARAMETER_NULL);
        }
        // 解析套餐实体
        Setmeal setmeal = BeanUtil.cloneBean(dto, Setmeal.class);
        setmeal.setUpdateTime(new Date());
        setmeal.setUpdateUser(LoginThreadLocal.getCurrent());
        // 更新
        updateById(setmeal);
        // 解析关联菜品
        List<SetmealDish> setmealDishes = dto.getSetmealDishes();
        if (!CollectionUtils.isEmpty(setmealDishes)) {
            // 先删后增
            setmealDishService.remove(Wrappers.<SetmealDish>lambdaQuery()
                    .eq(SetmealDish::getSetmealId, setmeal.getId()));
            setmealDishes.stream()
                    .filter(Objects::nonNull)
                    .forEach(setmealDish -> {
                        setmealDish.setSetmealId(setmeal.getId().toString());
                        setmealDish.setCreateUser(LoginThreadLocal.getCurrent());
                        setmealDish.setUpdateUser(LoginThreadLocal.getCurrent());
                        setmealDish.setCreateTime(new Date());
                        setmealDish.setUpdateTime(new Date());
                    });
            // 批量插入
            setmealDishService.saveBatch(setmealDishes);
        }
        return R.success("套餐修改成功");
    }

    /**
     * 批量上下架
     *
     * @param status
     * @param ids
     * @return
     */
    @Override
    public R updateStatus(Integer status, List<String> ids) {
        if ((1 != status && 0 != status) || CollectionUtils.isEmpty(ids)) {
            return R.error(HttpEnum.PARAMETER_ERROR);
        }
        List<Setmeal> setmealList = list(Wrappers.<Setmeal>lambdaQuery()
                .in(Setmeal::getId, ids)
                .eq(Setmeal::getIsDeleted, 0));
        setmealList.stream().forEach(setmeal -> {
            setmeal.setStatus(status);
            setmeal.setUpdateUser(LoginThreadLocal.getCurrent());
            setmeal.setUpdateTime(new Date());
        });
        // 批量修改
        updateBatchById(setmealList);
        return R.success(status == 0 ? "批量停售成功" : "批量起售成功");
    }
}

